 /*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * Project  : EasyAvatar-Lib
 * Package  : net.solosky.easyavatar.api.impl
 * File     : AbstractQQServiceFriendProvider.java
 * Author   : solosky < solosky772@qq.com >
 * Created  : Oct 29, 2011
 * License  : Apache License 2.0 
 */
package net.solosky.easyavatar.api.impl;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.solosky.easyavatar.api.ApiException;
import net.solosky.easyavatar.api.ErrorCode;
import net.solosky.easyavatar.api.http.HttpRequest;
import net.solosky.easyavatar.api.http.HttpResponse;
import net.solosky.easyavatar.api.util.QQEncryptor;

/**
 *
 * 抽象的QQ服务提供接口，提供QQ登录操作
 *
 * @author solosky <solosky772@qq.com>
 *
 */
public abstract class AbstractQQServiceFriendProvider extends AbstractWebFriendProvider{
	private static final String URL_CHECK     = "http://ptlogin2.qq.com/check";
	private static final String URL_LOGIN     = "http://ptlogin2.qq.com/login";
	private static final String URL_CAPATCHA  = "http://captcha.qq.com/getimage";
	private static final String REGXP_CHECK = "ptui_checkVC\\('(.*?)','(.*?)'\\);";
	private static final String REGXP_LOGIN = "ptuiCB\\('(\\d+)','(\\d+)','(.*?)','(\\d+)','(.*?)'\\)";
	
	/**如果登录需要验证，获取验证码时需要这个参数*/
	private String vcType;
	/**当前登录用户的ID,临时变量，仅在验证时有效*/
	private String uin;
	
	@Override
	public void signIn(String username, String password, String verifycode)
			throws ApiException, IOException {
		HttpRequest  req = null;
		HttpResponse res = null;
		
		//如果验证码为空，尝试自动登录
		if(verifycode==null){
			req = createHttpRequest(URL_CHECK, "GET");
			req.addGetValue("uin", username);
			req.addGetValue("appid",  getAppId());
			req.addGetValue("ptlang", "2052");
			req.addGetValue("r", ""+Math.random());
			System.out.println(req.getUrl());
			res = executeHttpRequest(req);
			System.out.println(res.getResponseString());
			Pattern pt = Pattern.compile(REGXP_CHECK);
			Matcher mc = pt.matcher(res.getResponseString());
			if(mc.find() && mc.group(1).equals("0")) {
				verifycode = mc.group(2);
			}else{
				vcType = mc.group(2);
				uin    = username;
			}
		}
		
		//如果仍为空，说明自动登录失败，强制使用验证码登录
		if(verifycode==null) throw new ApiException(ErrorCode.NEED_CAPTCHA);
		
		//尝试登录，准备传递的参数值
		req = createHttpRequest(URL_LOGIN, "GET");
		req.addGetValue("ptlang", "2052");
		req.addGetValue("u", username);
		req.addGetValue("p", QQEncryptor.encrypt(password, verifycode.toLowerCase()));
		req.addGetValue("verifycode", verifycode);
		req.addGetValue("aid", getAppId());
		req.addGetValue("u1", "http://imgcache.qq.com/qzone/v5/loginsucc.html?para=izone");
		req.addGetValue("ptredirect", "1");
		req.addGetValue("h", "1");
		req.addGetValue("from_ui", "1");
		req.addGetValue("dumy", "");
		req.addGetValue("fp", "loginerroralert");
		req.addGetValue("action", "3-15-14835");
		req.addGetValue("dummy", "");
		
		req.addHeader("Referer", "http://qzone.qq.com/");
		res = executeHttpRequest(req);
		validateResponse(res);
		
		 Pattern pt = Pattern.compile(REGXP_LOGIN);
	     Matcher mc = pt.matcher(res.getResponseString());
	     if(mc.find()){
	    	int ret = Integer.parseInt(mc.group(1));
	    	switch(ret){
		    	case 0: break;	//登录成功，什么也不做
		    	case 3: throw new ApiException(ErrorCode.WRONG_PASSWORD);
		    	case 4: throw new ApiException(ErrorCode.WRONG_CAPTCHA);
		    	default: throw new ApiException(ErrorCode.INVALID_USER);
	    	}
	     }else{
	    	 throw new ApiException(ErrorCode.INVALID_RESPONSE);
	     }
		
	}

	@Override
	public void signOut() throws ApiException, IOException {
	}

	@Override
	public byte[] retireCpatcha() throws ApiException, IOException {
		HttpRequest req = createHttpRequest(URL_CAPATCHA, "GET");
		req.addGetValue("aid", getAppId());
		req.addGetValue("vc_type", vcType);
		req.addGetValue("uin", uin);
		System.out.println(req.getUrl());
		HttpResponse res = executeHttpRequest(req);
		validateResponse(res);
		return res.getResponseData();
	}
	
	protected abstract String getAppId();
	
	protected String getUin(){
		String tuin = getHttpClient().getCookie("uin").getValue();
		return tuin.substring(1);
	}
}
